using DotNetCommon.Expressions.Base;
using DotNetCommon.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace DotNetCommon.Expressions.Visit
{
    /// <summary>
    /// 示例: new List&lt;int>(){1,2,3}
    /// </summary>
    internal class ListInitVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var listInitExpression = node.Expression as ListInitExpression;
            node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Expression = listInitExpression.NewExpression,
                Children = new List<ExpressionNode>(),
            });
            listInitExpression.Initializers.ForEach(i => node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = i.Arguments[0]
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var listInitExpression = node.Expression as ListInitExpression;
            return $"new {listInitExpression.Type.GetClassFullName()}(){{{node.Children.Select(i => i.FullMarkString).ToStringSeparated(",")}}}";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var listInitExpression = node.Expression as ListInitExpression;
            var inits = new List<ElementInit>();
            for (int i = 1; i < node.Children.Count; i++)
            {
                inits.Add(listInitExpression.Initializers[i - 1].Update(new[] { node.Children[i].Expression }));
            }
            return listInitExpression.Update(node.Children[0].Expression as NewExpression, inits);
        }
    }
}
